#include "StdAfx.h"
#include "MemoryPool.h"

#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

MemoryPool::MemoryPool(void)
{
}

MemoryPool::~MemoryPool(void)
{
	m_mbMemorys.clear();
}

bool MemoryPool::Init(unsigned int uiMemoryPoolSize/* = DEFAULT_POOL_SIZE*/, unsigned int uiBufferSize/* = DEFAULT_BUFFER_SIZE*/)
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> locker(m_mbLock);

	for (int i = 0; i < (int)uiMemoryPoolSize; i++)
	{
		ACE_Message_Block* pMemory = new ACE_Message_Block();
		if (pMemory)
		{
			pMemory->size(uiBufferSize);
			pMemory->set_flags(MEM_UNUSED);
			pMemory->reset();
			m_mbMemorys.push_back(pMemory);
		}
		else
		{
			return false;
		}
	}
	return true;
}

bool MemoryPool::UnInit()
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> locker(m_mbLock);
	std::list<ACE_Message_Block*>::iterator it;

	for (it = m_mbMemorys.begin(); it != m_mbMemorys.end(); it++)
	{
		if ((*it) == NULL)
			return false;
		delete (*it);
		(*it) = NULL;
	}

	return true;
}

ACE_Message_Block* MemoryPool::GetMemory()
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> locker(m_mbLock);
	std::list<ACE_Message_Block*>::iterator it;

	for (it = m_mbMemorys.begin(); it != m_mbMemorys.end(); it++)
	{
		if ((*it) == NULL)
			return NULL;

		if ((*it)->flags() == MEM_UNUSED)
			return (*it);
	}

	return NULL;
}

bool MemoryPool::ReleaseMemory(ACE_Message_Block* pMemory)
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> locker(m_mbLock);
	std::list<ACE_Message_Block*>::iterator it;

	for (it = m_mbMemorys.begin(); it != m_mbMemorys.end(); it++)
	{
		if ((*it) == NULL)
			return false;

		if ((*it) == pMemory)
		{
			if (pMemory->flags() == MEM_USED)
			{
				pMemory->reset();
				pMemory->set_flags(MEM_UNUSED);

				return true;
			}
		}
	}

	return false;
}

bool MemoryPool::AddMemory(unsigned int uiBufferSize/* = DEFAULT_BUFFER_SIZE*/)
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> locker(m_mbLock);
	
	ACE_Message_Block* pMemory = new ACE_Message_Block();
	if (pMemory)
	{
		pMemory->size(uiBufferSize);
		pMemory->set_flags(MEM_UNUSED);
		pMemory->reset();
		m_mbMemorys.push_back(pMemory);
	}
	else
	{
		return false;
	}

	return true;
}

bool MemoryPool::DelMemory(ACE_Message_Block* pMemory)
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> locker(m_mbLock);
	std::list<ACE_Message_Block*>::iterator it;

	for (it = m_mbMemorys.begin(); it != m_mbMemorys.end(); it++)
	{
		if (&(*it) == NULL)
		{
			return false;
		}

		if ((*it) == pMemory)
		{
			delete pMemory;
			m_mbMemorys.erase(it);

			return true;
		}
	}

	return false;
}